﻿////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// <copyright>Copyright 2008-2011 Andreas Huber Doenni</copyright>
// Distributed under the Microsoft Public License (Ms-PL).
// See accompanying file License.txt or copy at http://mews.codeplex.com/license.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

namespace Mews.Mime
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics.CodeAnalysis;
    using System.IO;
    using System.Linq;

    /// <summary>Represents a header field containing an address list (see
    /// <a href="http://www.ietf.org/rfc/rfc5322.txt">RFC 5322</a> 3.4.).</summary>
    /// <threadsafety static="true" instance="false"/>
    public sealed class AddressListHeaderField : HeaderField<AddressListHeaderField>
    {
        private readonly List<Address> addresses = new List<Address>();

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        /// <summary>Initializes a new instance of the <see cref="AddressListHeaderField"/> class.</summary>
        /// <param name="name">The name of the header field, e.g. <see cref="HeaderFieldNames.From"/>.</param>
        /// <exception cref="ArgumentException"><paramref name="name"/> is <c>null</c> or empty.</exception>
        public AddressListHeaderField(string name) : base(name)
        {
        }

        /// <summary>Gets the addresses.</summary>
        public IList<Address> Addresses
        {
            get { return this.addresses; }
        }

        /// <summary>Gets the body of the header field.</summary>
        /// <remarks>The default value is <see cref="string.Empty"/>, which is set during construction and when the
        /// parser does not find a valid body.</remarks>
        [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "Building the body might be expensive.")]
        public string GetBody()
        {
            return string.Concat((from part in this.GetAddressParts() select part.Part).ToArray());
        }

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        internal sealed override void WriteTo(Stream stream)
        {
            HeaderFieldHelper.FoldHeaderField(this.Name, this.GetAddressParts(), stream);
        }

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        private HeaderFieldBodyPart[] GetAddressParts()
        {
            var parts = new HeaderFieldBodyPart[this.addresses.Count * 2];

            for (int offset = 0; offset < parts.Length; offset += 2)
            {
                this.addresses[offset >> 1].WriteTo(parts, offset);
            }

            return parts;
        }
    }
}
